<i18n locale="en" lang="yaml">
lastStarted  : 'Started {t}'
lastSucceeded: 'Succeeded {t}'
lastFailed   : 'Failed {t}'
</i18n>

<i18n locale="zh-CN" lang="yaml">
Cron Jobs can be paused temporarily          : 定时任务可以临时暂停
Cron Jobs has been paused, will resume in {0}: 定时任务已暂停，将在 {0} 后继续
Cron Jobs has been paused                    : 定时任务已暂停

Resume              : 继续
Pause               : 暂停
Paused              : 已暂停
Pause for 15 minutes: 暂停 15 分钟
Pause for 30 minutes: 暂停 30 分钟
Pause for 1 hour    : 暂停 1 小时
Pause for 3 hours   : 暂停 3 小时
Pause for 12 hours  : 暂停 12 小时
Pause for 1 day     : 暂停 1 天

Fixed      : 固定
Dynamic    : 动态
Not Set    : 未配置
Cron Expr  : Cron 表达式
Config     : 配置
Created    : 创建
Expires    : 过期
Task Record: 任务记录
Run        : 执行

Cron Job disabled        : 定时任务已禁用
Cron Job enabled         : 定时任务已启用
Cron Job deleted         : 定时任务已删除
Cron Job Started Manually: 定时任务已手工启动

Show all contents: 展示全部内容
No Cron Job has ever been added: 从未添加过任何定时任务

Are you sure you want to disable the Cron Job?     : 是否确认禁用此定时任务？
Are you sure you want to delete the Cron Job?      : 是否确认删除此定时任务？
Are you sure you want to run the Cron Job manually?: 是否确认手动执行此定时任务？

lastStarted  : '{t}执行'
lastSucceeded: '{t}执行成功'
lastFailed   : '{t}执行失败'

No Recent Triggered Time Info: 无最近触发时间信息
Recent Triggered Time        : 最近触发时间
Trigger Time                 : 触发时间
Since Prev Cron Triggered    : 距上次 Cron 触发
Triggered Manually           : 手动触发
~~~ Repeated {n} Times ~~~   : ~~~ 重复 {n} 次 ~~~
Show Full Records            : 显示完整记录

Using Cron Job, you can have functions executed at regular intervals: 使用定时任务，可以让函数定时执行
</i18n>

<!-- Generated by OpenCC START -->
<i18n locale="zh-HK" lang="yaml">
Are you sure you want to delete the Cron Job?: 是否確認刪除此定時任務？
Are you sure you want to disable the Cron Job?: 是否確認禁用此定時任務？
Are you sure you want to run the Cron Job manually?: 是否確認手動執行此定時任務？
Config: 配置
Created: 創建
Cron Expr: Cron 表達式
Cron Job Started Manually: 定時任務已手工啓動
Cron Job deleted: 定時任務已刪除
Cron Job disabled: 定時任務已禁用
Cron Job enabled: 定時任務已啓用
Cron Jobs can be paused temporarily: 定時任務可以臨時暫停
Cron Jobs has been paused: 定時任務已暫停
Cron Jobs has been paused, will resume in {0}: 定時任務已暫停，將在 {0} 後繼續
Dynamic: 動態
Expires: 過期
Fixed: 固定
No Cron Job has ever been added: 從未添加過任何定時任務
No Recent Triggered Time Info: 無最近觸發時間信息
Not Set: 未配置
Pause: 暫停
Pause for 1 day: 暫停 1 天
Pause for 1 hour: 暫停 1 小時
Pause for 12 hours: 暫停 12 小時
Pause for 15 minutes: 暫停 15 分鐘
Pause for 3 hours: 暫停 3 小時
Pause for 30 minutes: 暫停 30 分鐘
Paused: 已暫停
Recent Triggered Time: 最近觸發時間
Resume: 繼續
Run: 執行
Show Full Records: 顯示完整記錄
Show all contents: 展示全部內容
Since Prev Cron Triggered: 距上次 Cron 觸發
Task Record: 任務記錄
Trigger Time: 觸發時間
Triggered Manually: 手動觸發
Using Cron Job, you can have functions executed at regular intervals: 使用定時任務，可以讓函數定時執行
lastFailed: '{t}執行失敗'
lastStarted: '{t}執行'
lastSucceeded: '{t}執行成功'
~~~ Repeated {n} Times ~~~: ~~~ 重複 {n} 次 ~~~
</i18n>
<i18n locale="zh-TW" lang="yaml">
Are you sure you want to delete the Cron Job?: 是否確認刪除此定時任務？
Are you sure you want to disable the Cron Job?: 是否確認禁用此定時任務？
Are you sure you want to run the Cron Job manually?: 是否確認手動執行此定時任務？
Config: 配置
Created: 建立
Cron Expr: Cron 表示式
Cron Job Started Manually: 定時任務已手工啟動
Cron Job deleted: 定時任務已刪除
Cron Job disabled: 定時任務已禁用
Cron Job enabled: 定時任務已啟用
Cron Jobs can be paused temporarily: 定時任務可以臨時暫停
Cron Jobs has been paused: 定時任務已暫停
Cron Jobs has been paused, will resume in {0}: 定時任務已暫停，將在 {0} 後繼續
Dynamic: 動態
Expires: 過期
Fixed: 固定
No Cron Job has ever been added: 從未新增過任何定時任務
No Recent Triggered Time Info: 無最近觸發時間資訊
Not Set: 未配置
Pause: 暫停
Pause for 1 day: 暫停 1 天
Pause for 1 hour: 暫停 1 小時
Pause for 12 hours: 暫停 12 小時
Pause for 15 minutes: 暫停 15 分鐘
Pause for 3 hours: 暫停 3 小時
Pause for 30 minutes: 暫停 30 分鐘
Paused: 已暫停
Recent Triggered Time: 最近觸發時間
Resume: 繼續
Run: 執行
Show Full Records: 顯示完整記錄
Show all contents: 展示全部內容
Since Prev Cron Triggered: 距上次 Cron 觸發
Task Record: 任務記錄
Trigger Time: 觸發時間
Triggered Manually: 手動觸發
Using Cron Job, you can have functions executed at regular intervals: 使用定時任務，可以讓函式定時執行
lastFailed: '{t}執行失敗'
lastStarted: '{t}執行'
lastSucceeded: '{t}執行成功'
~~~ Repeated {n} Times ~~~: ~~~ 重複 {n} 次 ~~~
</i18n>
<!-- Generated by OpenCC END -->

<template>
  <transition name="fade">
    <el-container direction="vertical" v-show="$store.state.isLoaded">
      <!-- Header area -->
      <el-header height="60px">
        <div class="common-page-header">
          <h1>{{ $t('Cron Job') }}</h1>
          <div class="header-control">
            <template v-if="T.notNothing(pauseTimeout)">
              <small>
                <i18n v-if="pauseTimeout > 0" path="Cron Jobs has been paused, will resume in {0}">
                  <el-tooltip effect="dark" :content="$tc('nSeconds', pauseTimeout)" placement="bottom">
                    <span class="text-bad">{{ T.duration(pauseTimeout * 1000, true) }}</span>
                  </el-tooltip>
                </i18n>
                <span v-else-if="pauseTimeout === -1" class="text-bad">{{ $t('Cron Jobs has been paused') }}</span>
              </small>

              <el-button v-if="pauseTimeout"
                size="small"
                type="success" plain
                @click="resumeAll()">
                <i class="fa fa-fw fa-play"></i>
                {{ $t('Resume') }}
              </el-button>
              <el-tooltip v-else effect="dark" :content="$t('Cron Jobs can be paused temporarily')" placement="left">
                <el-dropdown
                  split-button
                  size="small"
                  @click="pauseAll()"
                  @command="pauseAll">
                  <i class="fa fa-fw fa-pause"></i>
                  {{ $t('Pause') }}

                  <el-dropdown-menu slot="dropdown">
                    <el-dropdown-item :command="15 * 60">{{ $t('Pause for 15 minutes') }}</el-dropdown-item>
                    <el-dropdown-item :command="30 * 60">{{ $t('Pause for 30 minutes') }}</el-dropdown-item>
                    <el-dropdown-item :command="60 * 60">{{ $t('Pause for 1 hour') }}</el-dropdown-item>
                    <el-dropdown-item :command="3 * 60 * 60">{{ $t('Pause for 3 hours') }}</el-dropdown-item>
                    <el-dropdown-item :command="12 * 60 * 60">{{ $t('Pause for 12 hours') }}</el-dropdown-item>
                    <el-dropdown-item :command="24 * 60 * 60">{{ $t('Pause for 1 day') }}</el-dropdown-item>
                  </el-dropdown-menu>
                </el-dropdown>
              </el-tooltip>
            </template>

            <FuzzySearchInput :dataFilter="dataFilter"></FuzzySearchInput>

            <el-tooltip :content="$t('Show all contents')" placement="bottom" :enterable="false">
              <el-checkbox
                :border="true"
                size="small"
                v-model="dataFilter.origin"
                true-label="_ALL"
                false-label="user"
                @change="T.changePageFilter(dataFilter)">{{ $t('Show all') }}</el-checkbox>
            </el-tooltip>
            <el-button @click="openSetup(null, 'add')" type="primary" size="small">
              <i class="fa fa-fw fa-plus"></i>
              {{ $t('New') }}
            </el-button>
          </div>
        </div>
      </el-header>

      <!-- List area -->
      <el-main class="common-table-container">
        <div class="no-data-area" v-if="T.isNothing(data)">
          <h1 class="no-data-title" v-if="T.isPageFiltered({ ignore: { origin: '_ALL' } })"><i class="fa fa-fw fa-search"></i>{{ $t('No matched data found') }}</h1>
          <h1 class="no-data-title" v-else><i class="fa fa-fw fa-info-circle"></i>{{ $t('No Cron Job has ever been added') }}</h1>

          <p class="no-data-tip">
            {{ $t('Using Cron Job, you can have functions executed at regular intervals') }}
          </p>
        </div>
        <el-table v-else
          class="common-table" height="100%"
          :data="data"
          :row-class-name="common.getHighlightRowCSS">

          <el-table-column :label="$t('Func')" min-width="420">
            <template slot-scope="scope">
              <FuncInfo
                :config-func-id="scope.row.funcId"
                :id="scope.row.func_id"
                :title="scope.row.func_title"
                :kwargsJSON="scope.row.funcCallKwargsJSON" />

              <div>
                <span class="text-info">ID</span>
                &nbsp;<code class="text-main">{{ scope.row.id }}</code>
                <CopyButton :content="scope.row.id" />

                <template v-if="T.notNothing(scope.row.tagsJSON) || T.notNothing(scope.row.func_tagsJSON)">
                  <br>
                  <span class="text-info">&#12288;{{ $t('Tags') }}</span>
                  <el-tag size="mini" type="info" v-for="t in scope.row.func_tagsJSON" :key="t">{{ t }}</el-tag>
                  <el-tag size="mini" type="warning" v-for="t in scope.row.tagsJSON" :key="t">{{ t }}</el-tag>
                </template>

                <template v-if="scope.row.note">
                  <br>
                  <span class="text-info">&#12288;{{ $t('Note') }}{{ $t(':') }}</span>
                  <span>{{ scope.row.note }}</span>
                </template>
              </div>

              <InfoBlock v-if="scope.row.lastTaskStatus && scope.row.lastTaskStatus.exceptionTEXT"
                type="error" :title="scope.row.lastTaskStatus.exceptionTEXT" />
            </template>
          </el-table-column>

          <el-table-column :label="$t('Config')" width="255">
            <template slot-scope="scope">
              <span class="text-info">{{ $t('Cron Expr') }}{{ $t(':') }}</span>
              <template v-if="scope.row.isPaused">
                <el-tooltip effect="dark" :content="$t('expireAt2', { t: T.getDateTimeString(scope.row.pauseExpireTime * 1000) })" placement="right" :disabled="!!!scope.row.pauseExpireTime">
                  <el-tag type="danger" size="mini">{{ $t('Paused') }}</el-tag>
                </el-tooltip>
              </template>
              <template v-else-if="scope.row.dynamicCronExpr">
                <code class="text-bad">{{ scope.row.dynamicCronExpr }}</code>
                <el-tooltip effect="dark" :content="$t('expireAt2', { t: T.getDateTimeString(scope.row.dynamicCronExprExpireTime * 1000) })" placement="right" :disabled="!!!scope.row.dynamicCronExprExpireTime">
                  <el-tag type="danger" size="mini">{{ $t('Dynamic') }}</el-tag>
                </el-tooltip>
              </template>
              <template v-else-if="scope.row.func_extraConfigJSON && scope.row.func_extraConfigJSON.fixedCronExpr">
                <code class="text-main">{{ scope.row.func_extraConfigJSON.fixedCronExpr }}</code>
                <el-tag size="mini">{{ $t('Fixed') }}</el-tag>
              </template>
              <code v-else-if="scope.row.cronExpr" class="text-main">{{ scope.row.cronExpr }}</code>
              <span v-else class="text-bad">{{ $t('Not Set') }}</span>

              <br>
              <span class="text-info">{{ $t('Queue') }}{{ $t(':') }}</span>
              <span>
                #{{ scope.row.func_extraConfigJSON.queue || $store.getters.SYSTEM_INFO('_FUNC_TASK_QUEUE_CRON_JOB') }}
              </span>

              <br>
              <span class="text-info">{{ $t('Timeout') }}{{ $t(':') }}</span>
              <span v-if="scope.row.func_extraConfigJSON && scope.row.func_extraConfigJSON.timeout">
                {{ $tc('nSeconds', scope.row.func_extraConfigJSON.timeout) }}
              </span>
              <template v-else>
                {{ $tc('nSeconds', $store.getters.SYSTEM_INFO('_FUNC_TASK_TIMEOUT_DEFAULT')) }}
              </template>

              <br>
              <span class="text-info">{{ $t('Created') }}{{ $t(':') }}</span>
              <RelativeDateTime :datetime="scope.row.createTime" from-now-limit="before" />

              <template v-if="scope.row.expireTime">
                <br>
                <span class="text-info">{{ $t('Expires') }}{{ $t(':') }}</span>
                <RelativeDateTime :datetime="scope.row.expireTime"
                  :class="T.isExpired(scope.row.expireTime) ? 'text-bad' : 'text-good'" />
              </template>
            </template>
          </el-table-column>

          <el-table-column :label="$t('Status')" width="255">
            <template slot-scope="scope">
              <span v-if="scope.row.isDisabled" class="text-bad">
                <i class="fa fa-fw fa-ban"></i>
                {{ $t('Disabled') }}
              </span>
              <span v-else class="text-good">
                <i class="fa fa-fw fa-check"></i>
                {{ $t('Enabled') }}
              </span>

              <br>
              <el-tooltip placement="right" effect="dark" v-if="scope.row.lastTaskStatus">
                <div slot="content">
                  <span class="datetime-tip">{{ scope.row.lastTaskStatus.timestamp * 1000 | datetime }}</span>
                </div>
                <span v-if="scope.row.lastTaskStatus.status === 'started'" class="text-main">
                  <i class="fa fa-fw fa-circle-o-notch fa-spin"></i>
                  {{ $t('lastStarted', { t: T.toNow(scope.row.lastTaskStatus.timestamp * 1000) }) }}
                </span>
                <span v-else-if="scope.row.lastTaskStatus.status === 'success'" class="text-good">
                  <i class="fa fa-fw fa-check"></i>
                  {{ $t('lastSucceeded', { t: T.toNow(scope.row.lastTaskStatus.timestamp * 1000) }) }}
                </span>
                <span v-else-if="scope.row.lastTaskStatus.status === 'failure'" class="text-bad">
                  <i class="fa fa-fw fa-times"></i>
                  {{ $t('lastFailed', { t: T.toNow(scope.row.lastTaskStatus.timestamp * 1000) }) }}
                </span>
              </el-tooltip>
              <span v-else class="text-info">
                <i class="fa fa-fw fa-ellipsis-h"></i>
                {{ $t('No task record') }}
              </span>

              <br>
              <el-link v-if="scope.row.lastTaskStatus" @click="showRecentTriggered(scope.row.id)">
                <i v-if="loadingRecentTriggeredId !== scope.row.id" class="fa fa-fw fa-clock-o"></i>
                <i v-else class="fa fa-fw fa-circle-o-notch fa-spin"></i>
                {{ $t('Recent Triggered Time') }}
              </el-link>
            </template>
          </el-table-column>

          <el-table-column align="right" width="400">
            <template slot-scope="scope">
              <el-tooltip effect="dark" :content="scope.row.localFuncTaskRecordTip" placement="left" :disabled="!scope.row.localFuncTaskRecordTip">
                <el-badge class="task-record-button" type="primary" :max="99" :hidden="!funcTaskRecordCountMap[scope.row.id] || !scope.row.isLocalFuncTaskRecordAvailable" :value="funcTaskRecordCountMap[scope.row.id] && funcTaskRecordCountMap[scope.row.id].count || 0">
                  <el-link
                    @click="common.goToPage('task-record-func-list', { origin: 'cronJob', originId: scope.row.id }, { hlDataId: scope.row.id })"
                    :disabled="!scope.row.isLocalFuncTaskRecordAvailable">
                    {{ $t('Task Record') }}
                  </el-link>
                </el-badge>
              </el-tooltip>

              <el-link @click="runTask(scope.row)" :disabled="!scope.row.func_id">
                {{ $t('Run') }}
              </el-link>
              <el-link :disabled="T.isNothing(scope.row.func_id)" v-if="scope.row.isDisabled" v-prevent-re-click @click="quickSubmitData(scope.row, 'enable')">{{ $t('Enable') }}</el-link>
              <el-link :disabled="T.isNothing(scope.row.func_id)" v-if="!scope.row.isDisabled" @click="quickSubmitData(scope.row, 'disable')">{{ $t('Disable') }}</el-link>
              <el-link @click="openSetup(scope.row, 'setup')">{{ $t('Setup') }}</el-link>
              <el-link type="danger" @click="quickSubmitData(scope.row, 'delete')">{{ $t('Delete') }}</el-link>
            </template>
          </el-table-column>
        </el-table>
      </el-main>

      <!-- Paging area -->
      <Pager :pageInfo="pageInfo" />
      <CronJobSetup ref="setup" />

      <el-dialog
        :visible.sync="showRecentTriggeredDialog"
        :close-on-click-modal="false"
        width="600px">
        <template slot="title">
          {{ $t('Recent Triggered Time') }}
          <span class="press-esc-to-close-tip">{{ $t('Press ESC to close') }}</span>
        </template>
          <el-button type="text" v-if="latestRecentTriggeredMode !== 'full'" @click="showRecentTriggered(latestRecentTriggeredId, 'full')">{{ $t('Show Full Records') }}</el-button>
          <el-input type="textarea" resize="none" size="mini" :value="recentTriggeredData" readonly autosize></el-input>
      </el-dialog>
    </el-container>
  </transition>
</template>

<script>
import CronJobSetup from '@/components/Management/CronJobSetup'

export default {
  name: 'CronJobList',
  components: {
    CronJobSetup,
  },
  watch: {
    $route: {
      immediate: true,
      async handler(to, from) {
        await this.loadData();
      }
    },
    '$store.state.isLoaded': function(val) {
      if (!val) return;

      setImmediate(() => this.T.autoScrollTable());
    },
  },
  methods: {
    async loadData(options) {
      options = options || {};

      // Default filter
      let _listQuery = this.dataFilter = this.T.createListQuery();
      if (this.T.isNothing(this.$route.query)) {
        _listQuery.origin = 'user';
      }

      let apiRes = await this.T.callAPI_get('/api/v1/cron-jobs/do/list', {
        query: _listQuery,
      });
      if (!apiRes || !apiRes.ok) return;

      apiRes.data.forEach(d => {
        d.func_extraConfigJSON = d.func_extraConfigJSON || {};

        d.isLocalFuncTaskRecordAvailable = false;

        if (!this.isLocalFuncTaskRecordEnabled) {
          if (this.isGuanceDataUploadEnabled) {
            d.localFuncTaskRecordTip = this.$t('Local Func task record is disabled, while uploading to Guance is enabled');
          } else {
            d.localFuncTaskRecordTip = this.$t('Local Func task record is disabled');
          }

        } else if (!d.taskRecordLimit) {
          d.localFuncTaskRecordTip = this.$t('Number of recent task records to be kept is not specified');

        } else {
          d.isLocalFuncTaskRecordAvailable = true;
          if (this.isGuanceDataUploadEnabled) {
            d.localFuncTaskRecordTip = this.$t('Func task record uploading to Guance has also been enabled');
          }
        }
      });


      this.data = apiRes.data;
      this.pageInfo = apiRes.pageInfo;

      this.$store.commit('updateLoadStatus', true);

      // Get pause info
      await this.updatePauseTimeout();

      // Get Task Record count info
      if (this.isLocalFuncTaskRecordEnabled && !options.skipStatistic) {
        this.isFuncTaskRecordCountLoaded = false;
        setTimeout(async () => {
          this.funcTaskRecordCountMap = await this.common.getFuncTaskRecordCountMap('originId', this.data.map(d => d.id));
          this.isFuncTaskRecordCountLoaded = true;
        }, 1000);
      }
    },
    async quickSubmitData(d, operation) {
      switch(operation) {
        case 'disable':
          if (!await this.T.confirm(this.$t('Are you sure you want to disable the Cron Job?'))) return;
          break;

        case 'delete':
          if (!await this.T.confirm(this.$t('Are you sure you want to delete the Cron Job?'))) return;
          break;
      }

      let apiRes = null;
      switch(operation) {
        case 'disable':
          apiRes = await this.T.callAPI('post', '/api/v1/cron-jobs/:id/do/modify', {
            params  : { id: d.id },
            body    : { data: { isDisabled: true } },
            feedback: { okMessage: this.$t('Cron Job disabled') },
          });
          break;

        case 'enable':
          apiRes = await this.T.callAPI('post', '/api/v1/cron-jobs/:id/do/modify', {
            params  : { id: d.id },
            body    : { data: { isDisabled: false } },
            feedback: { okMessage: this.$t('Cron Job enabled') },
          });
          break;

        case 'delete':
          apiRes = await this.T.callAPI('/api/v1/cron-jobs/:id/do/delete', {
            params  : { id: d.id },
            feedback: { okMessage: this.$t('Cron Job deleted') },
          });
          break;
      }
      if (!apiRes || !apiRes.ok) return;

      this.$store.commit('updateHighlightedTableDataId', d.id);

      await this.loadData({ skipStatistic: true });
    },
    openSetup(d, target) {
      switch(target) {
        case 'add':
          this.$refs.setup.loadData();
          break;

        case 'setup':
          this.$store.commit('updateHighlightedTableDataId', d.id);
          this.$refs.setup.loadData(d.id);
          break;
      }
    },
    async runTask(d) {
      if (!await this.T.confirm(this.$t('Are you sure you want to run the Cron Job manually?'))) return;

      let apiRes = await this.T.callAPI('post', '/api/v1/cron/:id', {
        params  : { id: d.id },
        feedback: { okMessage: this.$t('Cron Job Started Manually') },
      });

      this.$store.commit('updateHighlightedTableDataId', d.id);
    },
    async pauseAll(expires) {
      expires = expires || -1;
      let apiRes = await this.T.callAPI('post', '/api/v1/temporary-flags/:id/do/set', {
        params: { id: 'pauseCronJobs' },
        body  : { expires: expires },
      });
      if (!apiRes || !apiRes.ok) return;

      await this.updatePauseTimeout();
    },
    async resumeAll() {
      let apiRes = await this.T.callAPI_get('/api/v1/temporary-flags/:id/do/clear', {
        params: { id: 'pauseCronJobs' },
      });
      if (!apiRes || !apiRes.ok) return;

      await this.updatePauseTimeout();
    },
    async showRecentTriggered(id, mode) {
      if (this.showRecentTriggeredDialog === true) {
        this.showRecentTriggeredDialog = false;
      }

      this.loadingRecentTriggeredId  = id;
      this.latestRecentTriggeredId   = id;
      this.latestRecentTriggeredMode = mode;

      let apiRes = await this.T.callAPI_get('/api/v1/cron-jobs/:id/recent-triggered/do/list', {
        params: { id: id },
      });
      if (!apiRes || !apiRes.ok) return;


      if (this.T.isNothing(apiRes.data)) {
        this.recentTriggeredData = this.$t('No Recent Triggered Time Info');

      } else {
        let nextRecentTriggeredData = apiRes.data;

        // Convert data
        let triggeredData = nextRecentTriggeredData.filter(x => x[1] === 'cronJob');
        for (let i = 0; i < triggeredData.length; i++) {
          if (i >= triggeredData.length - 1) break;
          triggeredData[i].push(triggeredData[i][0] - triggeredData[i + 1][0]);
        }

        let makeField = (title, width) => {
          title = `${title || ''}`;
          width = width || 0;
          let blankWidth = Math.max(0, width - this.T.textLength(title));
          return title + ' '.repeat(blankWidth);
        }

        const SEQ_FIELD_WIDTH  = 10;
        const TIME_FIELD_WIDTH = 50;

        let headerLine = '';
        headerLine += makeField('SEQ', SEQ_FIELD_WIDTH);
        headerLine += makeField(this.$t('Trigger Time'), TIME_FIELD_WIDTH);
        headerLine += makeField(this.$t('Since Prev Cron Triggered'));

        let nextRecentTriggeredLines = [
          headerLine,
          '-'.repeat(this.T.textLength(headerLine)),
        ];

        let _repeatCount = 0;
        nextRecentTriggeredData.forEach((d, index) => {
          let line = '';
          line += makeField(nextRecentTriggeredData.length - index, SEQ_FIELD_WIDTH);
          line += makeField(this.T.getDateTimeString(d[0] * 1000) + this.$t('(') + this.T.toNow(d[0] * 1000) + this.$t(')'), TIME_FIELD_WIDTH);

          if (d[1] === 'manual') {
            line += makeField(this.$t('Triggered Manually'));

          } else if (index === nextRecentTriggeredData.length - 1) {
            // Nope

          } else {
            const DAY_SECONDS    = 3600 * 24;
            const HOUR_SECONDS   = 3600;
            const MINUTE_SECONDS = 60;

            let diffStr = '+';
            let diff = d[2];
            if (diff === 0) {
              diffStr += ' ' + this.$tc('nSeconds', diff);
            } else {
              if (diff >= DAY_SECONDS) {
                diffStr += ' ' + this.$tc('nDays', parseInt(diff / DAY_SECONDS));
                diff = diff % (DAY_SECONDS);
              }
              if (diff >= HOUR_SECONDS) {
                diffStr += ' ' + this.$tc('nHours', parseInt(diff / HOUR_SECONDS));
                diff = diff % HOUR_SECONDS;
              }
              if (diff >= MINUTE_SECONDS) {
                diffStr += ' ' + this.$tc('nMinutes', parseInt(diff / MINUTE_SECONDS));
                diff = diff % MINUTE_SECONDS;
              }
              if (diff > 0) {
                diffStr += ' ' + this.$tc('nSeconds', diff);
              }
            }

            line += makeField(diffStr);
          }

          if (mode === 'full') {
            // Full version
            nextRecentTriggeredLines.push(line);

          } else {
            // Reduced version
            if (index === 0) {
              nextRecentTriggeredLines.push(line);

            } else {
              let prevD = nextRecentTriggeredData[index - 1];
              if (d[1] === 'cronJob' && prevD[1] === 'cronJob' && d[2] === prevD[2]) {
                _repeatCount++;
              } else {
                if (_repeatCount > 0) {
                  nextRecentTriggeredLines.push(makeField(null, SEQ_FIELD_WIDTH) + this.$tc('~~~ Repeated {n} Times ~~~', _repeatCount));
                  _repeatCount = 0;
                }
                nextRecentTriggeredLines.push(line);
              }
            }
          }
        });

        this.recentTriggeredData = nextRecentTriggeredLines.join('\n');
      }

      this.showRecentTriggeredDialog = true;

      setImmediate(() => {
        this.loadingRecentTriggeredId = null;
      })
    },
    async updatePauseTimeout() {
      let apiRes = await this.T.callAPI_get('/api/v1/temporary-flags/do/get', {
        query: { id: 'pauseCronJobs' },
      });
      if (!apiRes || !apiRes.ok) return;

      this.pauseTimeout = apiRes.data.pauseCronJobs.ttl || 0;
    },
  },
  computed: {
    isLocalFuncTaskRecordEnabled() {
      return !!this.$store.getters.SYSTEM_SETTINGS('LOCAL_FUNC_TASK_RECORD_ENABLED');
    },
    isGuanceDataUploadEnabled() {
      return !!this.$store.getters.SYSTEM_SETTINGS('GUANCE_DATA_UPLOAD_ENABLED');
    },
  },
  props: {
  },
  data() {
    let _pageInfo   = this.T.createPageInfo();
    let _dataFilter = this.T.createListQuery();

    return {
      data    : [],
      pageInfo: _pageInfo,

      funcTaskRecordCountMap     : {},
      isFuncTaskRecordCountLoaded: false,

      dataFilter: {
        _fuzzySearch: _dataFilter._fuzzySearch,
        origin      : _dataFilter.origin,
      },

      showRecentTriggeredDialog: false,
      loadingRecentTriggeredId : null,
      latestRecentTriggeredId  : null,
      latestRecentTriggeredMode: null,
      recentTriggeredData      : null,

      pauseTimeout: null,

      autoRefreshTimer: null,
    }
  },
  created() {
    this.$root.$on('reload.cronJobList', () => this.loadData({ skipStatistic: true }));

    this.autoRefreshTimer = setInterval(() => {
      this.updatePauseTimeout();
    }, 10 * 1000);
  },
  destroyed() {
    this.$root.$off('reload.cronJobList');

    if (this.autoRefreshTimer) clearInterval(this.autoRefreshTimer);
  },
}
</script>

<style scoped>
.task-record-button {
  margin-right: 15px;
}
.datetime-tip {
  font-size: 16px;
}
</style>

<style>
</style>
